package cn.bearspark.common.util;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * 处理显示时间的信息的工具类
 *
 * @author f
 */
public class TimeInfoUtil {

    /**
     * 显示"刚刚"的限制，一分钟之内显示 刚刚
     */
    private static final int RECENT_LIM = 1;

    /**
     * "刚刚"的时间信息
     */
    private static final String RECENT_TIME_INFO = "刚刚";

    /**
     * 一分钟的秒数
     */
    private static final int S_PRE_MIN = 60;

    /**
     * 显示分钟数的限制，最多显示 59分钟
     */
    private static final int MIN_LIM = 60;

    /**
     * 小于一小时的时间消息
     */
    private static final String MIN_TIME_INFO = "分钟前";

    /**
     * 一小时的分钟数
     */
    private static final int MIN_PRE_HOUR = 60;

    /**
     * 显示小时数的限制，最多显示 23小时
     */
    private static final int HOUR_LIM = 24;

    /**
     * 小于一天的时间消息
     */
    private static final String HOUR_TIME_INFO = "小时前";

    /**
     * 一天的小时数
     */
    private static final int HOUR_PRE_DAY = 24;

    /**
     * 昨天的时间格式
     */
    private static final DateTimeFormatter YESTERDAY_FORMAT = DateTimeFormatter.ofPattern("昨天 HH:mm");

    /**
     * 今天的时间格式
     */
    private static final DateTimeFormatter TODAY_FORMAT = DateTimeFormatter.ofPattern("今天 HH:mm");

    /**
     * 明天的时间格式
     */
    private static final DateTimeFormatter TOMORROW_FORMAT = DateTimeFormatter.ofPattern("明天 HH:mm");

    /**
     * 显示天数的限制，最多显示 3天前
     */
    private static final int DAY_LIM = 4;

    /**
     * 小于天的时间消息
     */
    private static final String DAY_TIME_INFO = "天前";

    /**
     * 今年的年份的时间格式
     */
    private static final DateTimeFormatter CURR_YEAR_FORMAT = DateTimeFormatter.ofPattern("MM月dd日");

    /**
     * 跨年的年份的时间格式
     */
    private static final DateTimeFormatter OVER_YEAR_FORMAT = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

    /**
     * 今年的时间的时间格式
     */
    private static final DateTimeFormatter CURR_YEAR_TIME_FORMAT = DateTimeFormatter.ofPattern("MM月dd日 HH:mm");

    /**
     * 跨年的时间的时间格式
     */
    private static final DateTimeFormatter OVER_YEAR_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm");

    /**
     * 获取过去的时间信息
     *
     * @param tar 待获取的时间
     * @return 待获取的时间的过去时间信息
     */
    public static String getPastTimeInfo(LocalDateTime tar) {
        LocalDateTime now = LocalDateTime.now();
        final long interval = Duration.between(tar, now).getSeconds();

        final long minute = interval / S_PRE_MIN;
        if (minute < RECENT_LIM) {
            return RECENT_TIME_INFO;
        } else if (minute < MIN_LIM) {
            return minute + MIN_TIME_INFO;
        }

        final long hour = minute / MIN_PRE_HOUR;
        if (hour < HOUR_LIM) {
            return hour + HOUR_TIME_INFO;
        }

        final long day = hour / HOUR_PRE_DAY;
        if (now.getDayOfYear() == tar.getDayOfYear() + 1) {
            return YESTERDAY_FORMAT.format(tar);
        } else if (day < DAY_LIM) {
            return day + DAY_TIME_INFO;
        }

        if (now.getYear() == tar.getYear()) {
            // 如果与当前时间在同一年，则格式为 "MM月dd日"
            return CURR_YEAR_FORMAT.format(tar);
        } else {
            // 如果与当前时间不在同一年，则格式为 "YYYY年MM月dd日"
            return OVER_YEAR_FORMAT.format(tar);
        }
    }

    /**
     * 获取固定的时间信息
     *
     * @param tar 待获取的时间
     * @return 待获取的时间的固定时间信息
     */
    public static String getFixedTimeInfo(LocalDateTime tar) {
        LocalDateTime now = LocalDateTime.now();

        int nowDay = now.getDayOfYear();
        int tarDay = tar.getDayOfYear();
        if (tarDay == nowDay - 1) {
            return YESTERDAY_FORMAT.format(tar);
        } else if (tarDay == nowDay) {
            return TODAY_FORMAT.format(tar);
        } else if (tarDay == nowDay + 1) {
            return TOMORROW_FORMAT.format(tar);
        }

        if (now.getYear() == tar.getYear()) {
            // 如果与当前时间在同一年，则格式为 "MM月dd日 HH:mm"
            return CURR_YEAR_TIME_FORMAT.format(tar);
        } else {
            // 如果与当前时间不在同一年，则格式为 "YYYY年MM月dd日 HH:mm"
            return OVER_YEAR_TIME_FORMAT.format(tar);
        }
    }

    /**
     * 获取剩余的时间信息
     *
     * @param tar 待获取的时间
     * @return 待获取的时间的剩余时间信息
     */
    public static String getRemainingTimeInfo(LocalDateTime tar) {
        LocalDateTime now = LocalDateTime.now();
        // 如果没有剩余的时间，则返回 "已过期"
        if (now.isAfter(tar)) {
            return "已过期";
        }

        final long interval = Duration.between(now, tar).getSeconds();

        long minute = interval / S_PRE_MIN;
        long hour = minute / MIN_PRE_HOUR;
        long day = hour / HOUR_PRE_DAY;

        minute -= hour * MIN_PRE_HOUR;
        hour -= day * HOUR_PRE_DAY;

        // 如果有剩余的时间，则返回 "剩d日H时m分"
        return String.format("剩%d天%d时%d分", day, hour, minute);
    }

    /**
     * 获取时段的时分秒信息
     *
     * @param duration 时段
     * @return 待获取时段的时分秒信息
     */
    public static String getTimeInfo(double duration) {
        long interval = (long) Math.ceil(duration);
        long minute = interval / S_PRE_MIN;
        long hour = minute / MIN_PRE_HOUR;
        long second = interval % S_PRE_MIN;
        return String.format("%d:%d:%d", hour, minute, second);
    }
}
